import * as THREE from 'three';
import Stats from 'stats.js';
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls';

// 初始化性能统计
export function initStats(type) {
  const panelType =
    typeof type !== undefined && type && !isNaN(type) ? parseInt(type) : 0;
  const stats = new Stats();
  stats.showPanel(panelType); // 0: fps, 1: ms, 2: mb, 3+: custom
  document.body.appendChild(stats.dom);
  return stats;
}

// 初始化渲染器
export function initRenderer(width, height, additionalProperties) {
  const props =
    typeof additionalProperties !== undefined && additionalProperties
      ? additionalProperties
      : {};
  const renderer = new THREE.WebGLRenderer(props);
  renderer.shadowMap.enabled = true;
  renderer.shadowMapSoft = true;
  renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  renderer.setClearColor(new THREE.Color(0x000000));
  renderer.setSize(width, height);
  document.getElementById('webgl-output').appendChild(renderer.domElement);
  return renderer;
}

// 初始化相机
export function initCamera(width, height, initialPosition) {
  const position =
    initialPosition !== undefined
      ? initialPosition
      : new THREE.Vector3(-30, 40, 30);
  const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);
  camera.position.copy(position);
  camera.lookAt(new THREE.Vector3(0, 0, 0));
  return camera;
}

// 添加房子和树
export function addHouseAndTree(scene) {
  // 创建围墙
  createBoundingWall(scene);
  // 创建地平面
  createGroundPlane(scene);
  // 创建房子
  createHouse(scene);
  // 创建树
  createTree(scene);

  function createBoundingWall(scene) {
    const wallLeft = new THREE.CubeGeometry(70, 2, 2);
    const wallRight = new THREE.CubeGeometry(70, 2, 2);
    const wallTop = new THREE.CubeGeometry(2, 2, 50);
    const wallBottom = new THREE.CubeGeometry(2, 2, 50);

    const wallMaterial = new THREE.MeshPhongMaterial({ color: 0xa0522d });

    const wallLeftMesh = new THREE.Mesh(wallLeft, wallMaterial);
    const wallRightMesh = new THREE.Mesh(wallRight, wallMaterial);
    const wallTopMesh = new THREE.Mesh(wallTop, wallMaterial);
    const wallBottomMesh = new THREE.Mesh(wallBottom, wallMaterial);

    wallLeftMesh.position.set(15, 1, -25);
    wallRightMesh.position.set(15, 1, 25);
    wallTopMesh.position.set(-19, 1, 0);
    wallBottomMesh.position.set(49, 1, 0);

    scene.add(wallLeftMesh);
    scene.add(wallRightMesh);
    scene.add(wallBottomMesh);
    scene.add(wallTopMesh);
  }

  function createGroundPlane(scene) {
    const planeGeometry = new THREE.PlaneGeometry(70, 50);
    const planeMaterial = new THREE.MeshPhongMaterial({
      color: 0x9acd32
    });
    const plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.receiveShadow = true;

    plane.rotation.x = -0.5 * Math.PI;
    plane.position.x = 15;
    plane.position.y = 0;
    plane.position.z = 0;

    scene.add(plane);
  }

  function createHouse(scene) {
    const roof = new THREE.ConeGeometry(5, 4);
    const base = new THREE.CylinderGeometry(5, 5, 6);

    const roofMesh = new THREE.Mesh(
      roof,
      new THREE.MeshPhongMaterial({
        color: 0x8b7213
      })
    );
    const baseMesh = new THREE.Mesh(
      base,
      new THREE.MeshPhongMaterial({
        color: 0xffe4c4
      })
    );

    roofMesh.position.set(25, 8, 0);
    baseMesh.position.set(25, 3, 0);

    roofMesh.receiveShadow = true;
    baseMesh.receiveShadow = true;
    roofMesh.castShadow = true;
    baseMesh.castShadow = true;

    scene.add(roofMesh);
    scene.add(baseMesh);
  }

  function createTree(scene) {
    const trunk = new THREE.CubeGeometry(1, 8, 1);
    const leaves = new THREE.SphereGeometry(4);

    const trunkMesh = new THREE.Mesh(
      trunk,
      new THREE.MeshPhongMaterial({
        color: 0x8b4513
      })
    );
    const leavesMesh = new THREE.Mesh(
      leaves,
      new THREE.MeshPhongMaterial({
        color: 0x00ff00
      })
    );

    trunkMesh.position.set(-10, 4, 0);
    leavesMesh.position.set(-10, 12, 0);

    trunkMesh.castShadow = true;
    trunkMesh.receiveShadow = true;
    leavesMesh.castShadow = true;
    leavesMesh.receiveShadow = true;

    scene.add(trunkMesh);
    scene.add(leavesMesh);
  }
}

// 在场景中添加一个简单的立方体和球体
export function addDefaultCubeAndSphere(scene) {
  // 添加一个立方体
  const cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
  const cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 });
  const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
  cube.castShadow = true;
  cube.position.set(-4, 3, 0);
  scene.add(cube);
  // 添加一个球体
  const sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
  const sphereMaterial = new THREE.MeshLambertMaterial({ color: 0x7777ff });
  const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
  sphere.position.set(20, 0, 2);
  sphere.castShadow = true;
  scene.add(sphere);
  // 返回立方体和球体
  return { cube, sphere };
}

// 在场景中添加一个简单的地面
export function addGroundPlane(scence) {
  const planeGeometry = new THREE.PlaneGeometry(60, 20, 120, 120);
  const planeMaterial = new THREE.MeshPhongMaterial({ color: 0xffffff });
  const plane = new THREE.Mesh(planeGeometry, planeMaterial);
  plane.receiveShadow = true;
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.set(15, 0, 0);
  scence.add(plane);
  return plane;
}

// 初始化轨迹球控件来控制场景
export function initTrackballControls(camera, renderer) {
  var trackballControls = new TrackballControls(camera, renderer.domElement);
  trackballControls.rotateSpeed = 1.0;
  trackballControls.zoomSpeed = 1.2;
  trackballControls.panSpeed = 0.8;
  trackballControls.noZoom = false;
  trackballControls.noPan = false;
  trackballControls.staticMoving = true;
  trackballControls.dynamicDampingFactor = 0.3;
  trackballControls.keys = [65, 83, 68];
  return trackballControls;
}
